﻿using Infra_Common.redis;
using MediatR;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using xiaodingmarket_Domain.Commands;
using xiaodingmarket_Domain.Events.Commodity;
using xiaodingmarket_Domain.Interfaces;
using xiaodingmarket_Domain.Interfaces.IRepository;
using xiaodingmarket_Domain.Models;
using xiaodingmarket_Domain_core.Bus;
using xiaodingmarket_Domain_core.Events;
using xiaodingmarket_Domain_core.Notificatiions;
using static xiaodingmarket_Domain.Models.EunmType;

namespace xiaodingmarket_Domain.CommandHandlers
{
    public class CommdityCommandHandler : CommandHandler,
        IRequestHandler<CreateNewCommodityCommand, bool>,  //Unit来代表无返回的情况
        IRequestHandler<ReviewCommodityCommand, bool>,
        IRequestHandler<UpdateCommodityCommand, bool>,
        IRequestHandler<RemoveCommodityCommand, bool>
    {

        // 注入仓储接口
        private readonly ICommodityRepository _CommodityRepository;
        //关于事件溯源，怎么记录，存进去什么值
        private readonly IEventStoreService _EventStoreService;
        // 注入总线
        private readonly IMediatorHandler Bus;
        //注入redis
        private readonly RedisClient redis;

        /// <summary>
        /// 构造函数注入
        /// </summary>
        /// <param name="studentRepository"></param>
        /// <param name="uow"></param>
        /// <param name="bus"></param>
        /// <param name="cache"></param>
        public CommdityCommandHandler(ICommodityRepository CommodityRepository,
                                      IEventStoreService EventStoreService,
                                      IUnitOfWork uow,
                                      IMediatorHandler bus,
                                      INotificationHandler<DomainNotification> notifications,
                                      RedisClient redisclient
                                      ) : base(uow, bus, notifications)
        {
            _CommodityRepository = CommodityRepository;
            _EventStoreService = EventStoreService;
            Bus = bus;
            redis = redisclient;
        }
        public Task<bool> Handle(CreateNewCommodityCommand message, CancellationToken cancellationToken)
        {
            // 命令验证
            if (!message.IsValid())
            {
                // 错误信息收集
                NotifyValidationErrors(message);
                // 返回，结束当前线程
                return Task.FromResult(false);
            }
            //创建商品领域模型并存储
            Guid CommodityId = Guid.NewGuid();
            Guid commoditydetailId = Guid.NewGuid();

            //截止日期与当前的日期时间差，小于一天的不审核，大于一天的需要审核，审核的商品id要存储redis，以便快速查询
            TimeSpan ts = message.endtime.Subtract(DateTime.Now).Duration();
            string date = ts.Days.ToString();
            if (int.Parse(date) >= 1)
            {
                var commoditydetail = new CommodityDetail(commoditydetailId, CommodityId, message.Detile, message.Title, "", "", message.Price, DateTime.Now, DateTime.Now, message.Id, message.Id, null);
                var commodity = new Commodity(CommodityId, message.Kind, message.Category, 0, 0, message.endtime, message.Remark, commoditydetail, null, Commoditystate.reviewing, false);

                _CommodityRepository.Add(commodity);
                //计算出应该截止的日期（增加一天），存到redis里,key失效触发回调的方式更新数据库
                DateTime endtime = message.endtime.AddDays(1);
                redis.Set<CommodityCreateEvent>("ReviewingCommodity_"+CommodityId, new CommodityCreateEvent(message.Id, CommodityId, message.Kind, message.Category, endtime),3600);
                
                if (Commit())
                {
                    //成功通知用户发布成功，正在审核
                    //Bus.RaiseEvent(new CommodityCreateEvent(message.Id, CommodityId, message.Kind, message.Category, endtime));
                }
            }
            else
            {
                //不要审核直接发布
                var commoditydetail = new CommodityDetail(Guid.NewGuid(), CommodityId, message.Detile, message.Title, "", "", message.Price, DateTime.Now, DateTime.Now, message.Id, message.Id, null);
                var commodity = new Commodity(CommodityId, message.Kind, message.Category, 0, 0, message.endtime, message.Remark, commoditydetail, null, Commoditystate.reviewok, false);
                _CommodityRepository.Add(commodity);

                if (Commit())
                {
                    //成功通知用户发布成功
                    //Bus.RaiseEvent(new CommodityCreateEvent(message.Id, CommodityId, message.Kind, message.Category, message.endtime));
                }
            }
            


            return Task.FromResult(false);
        }

        public Task<bool> Handle(ReviewCommodityCommand message, CancellationToken cancellationToken)
        {
            // 命令验证
            if (!message.IsValid())
            {
                // 错误信息收集
                NotifyValidationErrors(message);
                // 返回，结束当前线程
                return Task.FromResult(false);
            }
            var commodity = _CommodityRepository.GetOneById(message.Id);
            commodity.State = message.State;
            commodity.CommodityDetail.ModifyId = message.ModifyId;
            commodity.CommodityDetail.ModifyTime = DateTime.Now;


            _CommodityRepository.Update(commodity);

            if (Commit())
            {
                //Bus.RaiseEvent(new CommodityReviewEvent(message.Id,message.ModifyId,commodity.CommodityDetail.StudentId,commodity.CommodityDetail.ModifyTime));
            }

            return Task.FromResult(true);
        }

        public Task<bool> Handle(UpdateCommodityCommand message, CancellationToken cancellationToken)
        {
            // 命令验证
            if (!message.IsValid())
            {
                // 错误信息收集
                NotifyValidationErrors(message);
                // 返回，结束当前线程
                return Task.FromResult(false);
            }
            var commodity = _CommodityRepository.GetById(message.CommodityId);
            
            commodity.Kind = message.Kind?? commodity.Kind;
            commodity.Category = message.Category??commodity.Category;
            commodity.endtime = message.endtime??commodity.endtime;
            commodity.Remark = message.Remark?? commodity.Remark;
            commodity.CommodityDetail.Detile = message.Detile?? commodity.CommodityDetail.Detile;
            commodity.CommodityDetail.Title = message.Title?? commodity.CommodityDetail.Title;
            commodity.CommodityDetail.Price = message.Price??commodity.CommodityDetail.Price;

            _CommodityRepository.Update(commodity);
            if (Commit())
            {
                //Bus.RaiseEvent(new CommodityUpdateEvent(commodity.CommodityDetail.CommodityId, commodity.CommodityDetail.StudentId));
            }

            return Task.FromResult(true);
        }

        public Task<bool> Handle(RemoveCommodityCommand message, CancellationToken cancellationToken)
        {
            if (!message.IsValid())
            {
                NotifyValidationErrors(message);
                return Task.FromResult(false);
            }
            //逻辑删除
            var com=_CommodityRepository.GetById(message.Id);
            com.IsDelete = true;
            _CommodityRepository.Update(com);
            if (Commit())
            {
                //Bus.RaiseEvent(new CommodityRemoveEvent(message.Id));
            }

            return Task.FromResult(true);
        }
    }
}
